import axios from 'axios'
import { Message } from 'element-ui'
import {getToken, clearLocalStrorage} from '@/utils/LocalDataUtil'
import {clearSessionStorage} from '@/utils/SessionDataUtil'
import config from '@/config/index'
import Router from '@/router'
import CookieUtil from '@/utils/CookieUtil'
import ResultCodeHandle from '@/http/ResultCodeHandle'

const DEBUG = config.debug

axios.defaults.timeout = 60000
axios.defaults.baseURL = config.serverUrl()
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
axios.defaults.headers.put['Content-Type'] = 'application/json;charset=UTF-8'
axios.defaults.withCredentials = true // 传递session,很重要!很重要!很重要!

let cancel = {}
let promiseArr = {}
const CancelToken = axios.CancelToken
// http request 拦截器
/**
 * 拦截请求数据
 */
axios.interceptors.request.use(config => {
  if (promiseArr[config.url]) {
    promiseArr[config.url]('请勿重复操作')
    promiseArr[config.url] = cancel
  } else {
    promiseArr[config.url] = cancel
  }
  const token = getToken()
  if (token) {
    // 采用cookie存储token，且cookie为session模式
    // config.headers['token'] = token
  }
  if (DEBUG) {
    console.log(config)
  }
  return config
}, error => {
  return Promise.reject(error)
})
/**
 * 拦截响应数据
 */
axios.interceptors.response.use(response => {
  if (DEBUG) {
    console.log('Response status: ' + JSON.stringify(response.status))
    console.log('Response data: ' + JSON.stringify(response.data))
  }
  checkResponseCode(response.data)
  return response
}, error => {
  if (DEBUG) {
    console.log('Response Error Data: ' + JSON.stringify(error))
  }
  if (error.message && error.message === 'Network Error') {
    alterMessage('服务正在重启， 请稍后再试!')
    return
  }
  if (error && error.response && error.response.data) {
    checkResponseCode(error.response.data)
    return
  }
  if (axios.isCancel(error)) { // 取消请求的情况下，终端Promise调用链
    return new Promise(() => {})
  } else {
    return Promise.reject(error)
  }
})

function checkResponseCode (data) {
  let code = data.code
  if (code === '401') {
    clearSessionStorage()
    clearLocalStrorage()
    CookieUtil.clearToken()
    Router.push({name: 'login', params: {error: 'Unauthorized'}})
    return false
  } else {
    let message = ResultCodeHandle.response2Message(data)
    if (message) {
      alterMessage(message)
    }
  }
}

function alterMessage (msg) {
  if (msg !== null) {
    Message({
      showClose: true,
      message: msg,
      type: 'error',
      duration: 3000
    })
  }
}

export default {
  get (url, param) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'get',
        url,
        params: param,
        cancelToken: new CancelToken(c => {
          cancel = c
        })
      }).then(res => {
        resolve(res.data)
      }).catch(err => {
        resolve(err)
      })
    })
  },
  post (url, data) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'post',
        url,
        data: data,
        cancelToken: new CancelToken(c => {
          cancel = c
        })
      }).then(res => {
        resolve(res.data)
      }).catch(err => {
        resolve(err)
      })
    })
  },
  put (url, data) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'put',
        url,
        data: data,
        cancelToken: new CancelToken(c => {
          cancel = c
        })
      }).then(res => {
        resolve(res.data)
      }).catch(err => {
        resolve(err)
      })
    })
  },
  delete (url, param) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'delete',
        url,
        cancelToken: new CancelToken(c => {
          cancel = c
        })
      }).then(res => {
        resolve(res.data)
      }).catch(err => {
        resolve(err)
      })
    })
  },
  request (method, url, data) {
    if (!method || !url) {
      console.log('Method or Url is undefind!')
      return
    }
    method = method.toLowerCase()
    if (method === 'get') {
      return this.get(url, data)
    }
    if (method === 'post') {
      return this.post(url, data)
    }
    if (method === 'delete') {
      return this.delete(url, data)
    }
    if (method === 'put') {
      return this.put(url, data)
    }
  },
  req (path, data) {
    if (!path) {
      console.log('Path is undefind!')
      return
    }
    // TODO 对象或是字符串
    let method = path.method
    let uri = path.uri
    return this.request(method, uri, data)
  },
  async syncReq (url, param) {
    let result = await axios({
      method: 'get',
      url,
      params: param,
      cancelToken: new CancelToken(c => {
        cancel = c
      })
    })
    return result
  }
}

/**
 * 封装get方法
 * @param url
 * @param data
 * @returns {Promise}
 */
export function fetch (url, params = {}) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: params
    }).then(response => {
      resolve(response.data)
    }).catch(err => {
      reject(err)
    })
  })
}
/**
 * 封装post请求
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post (url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.post(url, data).then(response => {
      resolve(response.data)
    }, err => {
      reject(err)
    })
  })
}
/**
 * 封装delete请求
 * @param url
 * @param data
 * @returns {Promise}
 */
export function del (url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.delete(url, data)
      .then(response => {
        resolve(response.data)
      }, err => {
        reject(err)
      })
  })
}

/**
 * 封装put请求
 * @param url
 * @param data
 * @returns {Promise}
 */
export function put (url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.put(url, data)
      .then(response => {
        resolve(response.data)
      }, err => {
        reject(err)
      })
  })
}
